package com.caocaog.market.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caocaog.market.entity.GoodsBase;
import com.caocaog.market.entity.dto.GoodsDTO;
import com.caocaog.market.entity.vo.GoodsVO;
import com.caocaog.market.mapper.GoodsBaseMapper;
import com.caocaog.market.service.GoodsBaseService;
import com.caocaog.market.service.GoodsHubService;
import com.caocaog.market.service.GoodsService;
import com.caocaog.market.service.ShopTypeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.RedisUtil;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@EnableAsync
@RequiredArgsConstructor
public class GoodsHubServiceImpl implements GoodsHubService {

    private final RedisUtil redisUtil;
    private final GoodsService goodsService;
    private final ShopTypeService shopTypeService;
    private final GoodsBaseService goodsBaseService;
    private final GoodsBaseMapper goodsBaseMapper;
    private static final String SHOP_ID = "0";
    /**
     * 固定排序字段
     */
    private static final List<OrderItem> ORDER_ITEM_LIST = Arrays.asList(
            new OrderItem("sort", false),
            new OrderItem("sale_num", false),
            new OrderItem(CommonConstant.DEFAULT_ORDER_COLUMN, false)
    );


    @Override
    public IPage<GoodsBase> queryGoodsHubPage(Page<GoodsBase> page, GoodsBase goodsBase) {
        page.setOrders(ORDER_ITEM_LIST);
        goodsBase.setShopId(SHOP_ID);

        return goodsBaseMapper.queryGoodsBasePage(page, goodsBase);
    }


    @Override
    public List<GoodsVO> getGoodsHubListByShopTypeId(Long shopTypeId) {
        Assert.notNull(shopTypeId, "shopTypeId must not be null!");

        List<GoodsVO> allGoodsList = goodsService.getGoodsInfoByCategoriesId(shopTypeId.toString());

        // 根据 saleNum 给商品排序(desc)
        return allGoodsList.stream()
                .sorted(Comparator.comparing(GoodsVO::getSaleNum).thenComparing(GoodsVO::getId).reversed())
                .collect(Collectors.toList());
    }


    @Override
    public GoodsVO addGoodsHub(GoodsDTO goods) {
        Assert.isTrue(StringUtils.isNotBlank(goods.getSorts()), "shopTypeId must not be null!");

        Long shopTypeId = Long.valueOf(goods.getSorts());
        Assert.notNull(shopTypeService.getShopTypeById(shopTypeId), "未找到相应的店铺分类, shopTypeId-> " + shopTypeId);

        return goodsService.addGoods(goods.setShopId(SHOP_ID));
    }


    @Override
    public GoodsVO editGoodsHub(GoodsDTO goods) {
        goods.setSorts(null);
        return goodsService.editGoods(goods.setShopId(SHOP_ID));
    }


    @Override
    public int deleteGoodsHub(String... ids) {
        return goodsService.deleteGoods(ids);
    }


    @Override
    @Transactional
    public int batchImportGoods(List<GoodsDTO> goodsDTOList) {
        int count = 0;
        for (GoodsDTO goodsDTO : goodsDTOList) {
            count = count + (Objects.isNull(goodsService.addGoods(goodsDTO)) ? 0 : 1);
        }
        Map<String, Long> map = goodsDTOList.stream().collect(Collectors.groupingBy(GoodsDTO::getId, Collectors.counting()));
        for (Map.Entry<String, Long> entry : map.entrySet()) {
            addUsageCount(entry.getKey(), Math.toIntExact(entry.getValue()));
        }
        return count;
    }


    /**
     * 增加商品库使用次数
     *
     * @param id    商品库商品id
     * @param count 使用次数
     */
    @Async
    public void addUsageCount(String id, int count) {
        GoodsBase goodsBase = goodsBaseService.getByIdCache(id);
        goodsBaseService.updateCache(new GoodsBase().setId(id).setSaleNum(count + goodsBase.getSaleNum()));
        // 删除 GOODS_LIST_BY_CATEGORIES_ID 缓存
        this.redisUtil.del(GoodsBaseServiceImpl.getGoodsListByCategoriesIdKey(goodsBase));
    }

}
